package com.roshan.domain;

import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@SuppressWarnings( {"nls", "unchecked"})
@MappedSuperclass
public abstract class BaseDomain<S extends Serializable> implements Serializable {

    private static final long serialVersionUID = 100L;

    @Id
    @GeneratedValue
    @Column(name = "ID", nullable = false, unique = true, updatable = false)
    private S id;

    @Column(name = "URI", updatable = false)
    private String uri;

    @Column(name = "CREATE_DATE", updatable = false)
    private Date createDate;

    @Column(name = "LAST_MODIFIED_DATE")
    private Date lastModifiedDate;

    @Column(name = "ACTIVE")
    private boolean active = true;

    @Column(name = "DELETED")
    private boolean deleted;

    protected BaseDomain() {
        super();
    }

    public S getId() {
        return this.id;
    }

    public Date getCreateDate() {
        return this.createDate;
    }

    public Date getLastModifiedDate() {
        return this.lastModifiedDate;
    }

    public URI getUri() {
        try {
            return new URI(this.uri);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public void setId(final S id) {
        this.id = id;
    }

    public void setUri(final URI uri) {
        this.uri = uri.toString();
    }

    public void setCreateDate(final Date createDate) {
        this.createDate = createDate;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((this.createDate == null) ? 0 : this.createDate.hashCode());
        result = prime * result + ((this.lastModifiedDate == null) ? 0 : this.lastModifiedDate.hashCode());
        result = prime * result + ((this.uri == null) ? 0 : this.uri.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        BaseDomain other = (BaseDomain) obj;
        if (this.createDate == null) {
            if (other.createDate != null)
                return false;
        } else if (!this.createDate.equals(other.createDate))
            return false;
        if (this.lastModifiedDate == null) {
            if (other.lastModifiedDate != null)
                return false;
        } else if (!this.lastModifiedDate.equals(other.lastModifiedDate))
            return false;
        if (this.uri == null) {
            if (other.uri != null)
                return false;
        } else if (!this.uri.equals(other.uri))
            return false;
        return true;
    }

    public void setLastModifiedDate(final Date lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }

    public boolean isActive() {
        return this.active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public boolean isDeleted() {
        return this.deleted;
    }

    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

    @Override
    public String toString() {
        return "id=" + this.id + ", uri=" + this.uri + ", createDate=" + this.createDate + ", lastModifiedDate="
                + this.lastModifiedDate;
    }

}
